package com.neusoft.neuiotms.dcam.fixed.service.impl;

import java.text.ParseException;
import java.util.List;
import java.util.stream.Collectors;

import javax.persistence.EntityNotFoundException;

import org.apache.commons.compress.utils.Lists;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.cxf.common.util.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import com.neusoft.bizcore.web.constant.ExceptionConstants;
import com.neusoft.bizcore.web.exception.UnitedException;
import com.neusoft.bizcore.web.support.Searchable;
import com.neusoft.neuiotms.common.constant.AHConstants;
import com.neusoft.neuiotms.dcam.anhui.itsm.ContractBean;
import com.neusoft.neuiotms.dcam.fixed.converter.ContractConverter;
import com.neusoft.neuiotms.dcam.fixed.dto.ContractDTO;
import com.neusoft.neuiotms.dcam.fixed.dto.ContractItemDTO;
import com.neusoft.neuiotms.dcam.fixed.dto.ProductDTO;
import com.neusoft.neuiotms.dcam.fixed.model.AssetType;
import com.neusoft.neuiotms.dcam.fixed.model.Contract;
import com.neusoft.neuiotms.dcam.fixed.model.Product;
import com.neusoft.neuiotms.dcam.fixed.repository.AssetTypeRepository;
import com.neusoft.neuiotms.dcam.fixed.repository.ContractRepository;
import com.neusoft.neuiotms.dcam.fixed.repository.ProductRepository;
import com.neusoft.neuiotms.dcam.fixed.service.ContractItemService;
import com.neusoft.neuiotms.dcam.fixed.service.ContractService;
import com.neusoft.neuiotms.dcam.fixed.service.ProductService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Service
public class ContractServiceImpl implements ContractService {

    @Autowired
    private ContractRepository contractRepository;
    @Autowired
    private ContractConverter contractConverter;
    @Autowired
    private ContractItemService contractItemService;
    //    @Autowired
    //    private AssetService assetService;
    @Autowired
    private AssetTypeRepository assetTypeRepository;
    @Autowired
    private ProductService productService;
    @Autowired
    private ProductRepository productRepository;

    @Override
    public List<ContractDTO> findAll() {
        final List<Contract> models = this.contractRepository.findAll();
        return this.contractConverter.toListDTO(models);
    }

    @Override
    public Page<ContractDTO> search(final Pageable pageable, final Searchable searchable) {
        final Page<Contract> result = this.contractRepository.search(pageable, searchable);
        return this.contractConverter.toPageDTO(result);
    }

    @Override
    public ContractDTO create(final ContractDTO dto) {

        // 校验编码重复性
        final Contract check = this.contractRepository.findByCode(dto.getCode());
        if (check != null) {
            throw new UnitedException("合同号不能重复", new Object[] {});
        }

        // 创建合同
        final Contract model = this.contractConverter.toModel(dto);
        this.contractRepository.save(model);

        final ContractDTO result = this.contractConverter.toDTO(model);

        // 创建合同项
        dto.getItems().stream().map(k -> {
            k.setContractId(model.getId());
            return this.contractItemService.create(k);
        }).forEach(result.getItems()::add);

        return result;
    }

    @Override
    public ContractDTO details(final Long id) {
        final Contract model;
        try {
            model = this.contractRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        return this.contractConverter.toDTO(model);
    }

    @Override
    public void delete(final Long id) {

        final Contract model;

        try {
            model = this.contractRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        // final Searchable searchable = new Searchable();
        // searchable.put("contractId", id);
        // final Page<AssetDTO> assets = this.assetService.search(Pageable.unpaged(), searchable);
        // if (assets.getTotalElements() > 0) {
        //     throw new UnitedException("此合同已有资产，请先删除资产", new Object[] {id });
        // }

        try {
            // 删除合同项
            model.getItems().forEach(u -> {
                this.contractItemService.delete(u.getId());
            });

            // 删除合同
            this.contractRepository.deleteById(id);

        } catch (final Exception e) {
            throw new UnitedException("此合同已经生成业务数据，不能删除", new Object[] {id });
        }

    }

    @Override
    public ContractDTO update(final Long id, final ContractDTO dto) {

        // 校验编码重复性
        //        final Contract check = this.contractRepository.findByCode(dto.getCode());
        //        if ((check != null) && (check.getId() != id)) {
        //            throw new UnitedException("合同号不能重复", new Object[] {});
        //        }

        Contract model;
        try {
            model = this.contractRepository.getOne(id);
        } catch (final EntityNotFoundException e) {
            throw new UnitedException(ExceptionConstants.ENTITY_NOT_FOUND, new Object[] {id });
        }

        final List<Long> items = model.getItems().stream().map(k -> k.getId()).collect(Collectors.toList());

        dto.setId(model.getId());
        model = this.contractConverter.toModel(dto);

        // 更新合同
        model.getItems().clear();
        this.contractRepository.save(model);
        final ContractDTO result = this.contractConverter.toDTO(model);

        // 合同项
        dto.getItems().stream().map(k -> {
            k.setContractId(id);
            if (null != k.getId()) {
                items.remove(k.getId());
                return this.contractItemService.update(k.getId(), k);
            } else {
                return this.contractItemService.create(k);
            }
        }).forEach(result.getItems()::add);

        // 删除去掉的合同详细
        if ((items != null) && (items.size() > 0)) {
            // 删除合同项
            items.forEach(u -> {
                this.contractItemService.delete(u);
            });
        }
        return result;
    }

    @Override
    public ContractDTO createFromItsm(final ContractBean dto) {
    	log.info("createFromItsm() begin +++++++++++++++++");
    	log.info("createFromItsm() dto.getContractId() = "+dto.getContractId());
    	
        // 校验编码重复性
        final Contract check = this.contractRepository.findByCode(dto.getContractId());
        if (check != null) {
        	log.info("createFromItsm() end 合同号不能重复 +++++++++++++++++");
            throw new UnitedException("合同号不能重复");
        }

        final Contract model = new Contract();

        model.setCode(dto.getContractId());
        model.setName(dto.getContractName());
        model.setType("purchase");
        model.setBelongs(AHConstants.BELONG_KJ_CODE);
        model.setManufacturerName(dto.getAssetFirm());
        //        final Manufacturer manufacturer = this.manufacturerRepository.findByName(dto.getAssetFirm());
        //        if (null != manufacturer) {
        //            model.setManufacturer(manufacturer);
        //        }

        if (StringUtils.isNotBlank(dto.getProcessTime())) {
            try {
                model.setUpdateTime(DateUtils.parseDate(dto.getProcessTime(), "yyyy-MM-dd HH:mm:ss"));
            } catch (final ParseException e) {
            	log.info(" ParseException +++++++++++++++++");
            }
        }

        final List<ContractBean.AssetBean> assetList = dto.getAssetList();

        final List<ContractItemDTO> items = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(assetList)) {
            for (final ContractBean.AssetBean asset : assetList) {
                final AssetType assetType = this.assetTypeRepository.findByCode(asset.getAssetClassID());
                if (null == assetType) {
                    ContractServiceImpl.log.warn("{} is an invalid asset type, ignore it", asset.getAssetClassID());
                    continue;
                }

                final List<Product> products =
                        this.productRepository.findByAssetTypeAndNameAndBrandAndSpecification(assetType,
                                asset.getAssetName(),
                                asset.getAssetSign(), asset.getAssetModel());
                long productId = 0;
                if (products.size() == 0) {
                    ProductDTO productDTO = new ProductDTO();
                    productDTO.setBelongs(AHConstants.BELONG_KJ_CODE);
                    productDTO.setAssetTypeCode(assetType.getCode());
                    productDTO.setName(asset.getAssetName());
                    productDTO.setBrand(asset.getAssetSign());
                    productDTO.setSpecification(asset.getAssetModel());
                    productDTO.setMoney(asset.getAssetPrice());
                    productDTO.setMeasureUnit(asset.getAssetUnit());
                    productDTO = this.productService.create(productDTO);
                    productId = productDTO.getId();
                } else {
                    productId = products.get(0).getId();
                }

                final ContractItemDTO item = new ContractItemDTO();
                item.setAssetTypeCode(assetType.getCode());
                item.setAssetTypeName(assetType.getName());
                item.setProductId(productId);
                item.setProductName(asset.getAssetName());
                item.setCount(asset.getAssetNumber());
                item.setAmount(asset.getAssetPrice());
                item.setStandard(asset.getAssetModel());
                item.setType(asset.getAssetType());
                items.add(item);

            }
        }

        //        if (items.size() == 0) {
        //            throw new UnitedException("没有合格的资产数据");
        //        }

        log.info(" save contract begin +++++++++++++++++");
        this.contractRepository.save(model);
        log.info(" save contract end +++++++++++++++++");

        final ContractDTO result = this.contractConverter.toDTO(model);

        // 创建合同项
//        items.stream().map(k -> {
//            k.setContractId(model.getId());
//            k.setContractName(model.getName());
//            return this.contractItemService.create(k);
//        }).forEach(result.getItems()::add);
        
        log.info(" items.size() = "+items.size());
        
        if(!CollectionUtils.isEmpty(items))
        {
        	for(int i=0;i<items.size();i++)
        	{
        		items.get(i).setContractId(model.getId());
        		items.get(i).setContractName(model.getName());
        		if(items.get(i).getCount()>0)
        		{
        			int itemCount = items.get(i).getCount();
        			for(int j=0;j<itemCount;j++)
        			{
        				items.get(i).setCount(1);
        				result.getItems().add(this.contractItemService.create(items.get(i)));
        			}
        		}
        		
        	}
        }
        

        return result;
    }

}
